package cool.taomu.toolkit.service.centre.kademlia.service

import com.google.common.base.Optional
import com.google.inject.Inject
import com.google.inject.name.Named
import cool.taomu.toolkit.quartz.ScheduledJob
import cool.taomu.toolkit.service.centre.kademlia.utils.PeerConfigureFileDownload
import cool.taomu.toolkit.service.kademlia.entity.Constant
import cool.taomu.toolkit.service.kademlia.entity.FindNodeEntity
import cool.taomu.toolkit.service.kademlia.entity.KPeerNode
import cool.taomu.toolkit.service.kademlia.service.ICheckPeer
import cool.taomu.toolkit.service.kademlia.service.KRoutingTable
import java.io.File
import java.util.List
import java.util.concurrent.PriorityBlockingQueue
import java.util.function.Function
import org.eclipse.xtend.lib.annotations.Accessors
import org.slf4j.LoggerFactory

interface ICheckRemoteNode {
    def void pingQ()

    def void setBq(PriorityBlockingQueue<KPeerNode> bq)

    def PriorityBlockingQueue<KPeerNode> getBq();
}

@Accessors
class CheckRemoteNode implements ICheckRemoteNode {
    val static LOG = LoggerFactory.getLogger(CheckRemoteNode)

    var PriorityBlockingQueue<KPeerNode> bq = new PriorityBlockingQueue<KPeerNode>();

    @Inject
    ICheckPeer checkPeer;

    @Inject
    PeerConfigureFileDownload pConfigure;

    @Inject
    KRoutingTable router;

    @Inject
    @Named("taomu.toolkit.kademlia.findNode")
    Function<FindNodeEntity, List<KPeerNode>> findNode

    @ScheduledJob(cron="0/30 * * * * ?")
    override pingQ() {
        LOG.info("***** ping节点数量:{},K桶数量:{} *****", bq.size, router.ksize)
        // TODO 功能不完整 后期在改
        bq.forEach [ peer |
            if (this.checkPeer.apply(peer)) {
                // this.checkPeer为 检查 远程端 节点的
                var key = #[peer.host, peer.port, "local", "json"].join(".")
                var keyFilePath = #[Constant.TORRENT_DOWNLOAD_PATH, key].join(File.separator)
                if (!new File(keyFilePath).exists) {
                    if (pConfigure.downlaodTorrent(peer) && new File(keyFilePath).exists) {
                        LOG.info("配置文件 {} 下载完成", key)
                        var excludeIds = newArrayList();
                        excludeIds.add(this.router.localNode.id)
                        var optional = Optional.fromNullable(
                            findNode.apply(
                                new FindNodeEntity(this.router.localNode.id, peer, this.router.localNode, excludeIds)
                            )
                        )
                        if (optional.present) {
                            optional.get().forEach [
                                var key2 = #[it.host, it.host, "local", "json"].join(".")
                                if (!new File(#[Constant.TORRENT_DOWNLOAD_PATH, key2].join(File.separator)).exists) {
                                    if (pConfigure.downlaodTorrent(peer)) {
                                        LOG.info("optional 配置文件 {} 下载完成", key2)
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
    }
}
